#pragma once

#include <windows.h>
#include <dshow.h>
// See http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/ed097d2c-3d68-4f48-8448-277eaaf68252/
#pragma include_alias( "dxtrans.h", "qedit.h" )
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__
#include "qedit.h"

#include <vector>
#include "DisholCriticalSectionEnterer.h"
#include "DisholCOMObjectSharedPtr.h"
#include "DisholCaptureSettings.h"
#include "DisholMemoryBuffer.h"

namespace Dishol
{

class DeviceInternals 
{
public:
	DeviceInternals( COMObjectSharedPtr<IMoniker> moniker );
	virtual ~DeviceInternals();

	class VideoMediaType
	{
	public:
		VideoMediaType();					
		LONG				width ;
		LONG				height;
		bool				needVerticalFlip;
		LONGLONG			frameInterval;
		GUID				subType;
		
				
		std::string			getSubTypeName() const		{ return getSubTypeName(subType); }
		static std::string	getSubTypeName( const GUID& mediaType );
		
		float				getFrameRate() const;

		std::string			toString() const;

		bool				operator==( const VideoMediaType& other ) const;
		bool				operator!=( const VideoMediaType& other ) const;
	};
	typedef std::vector<VideoMediaType> VideoMediaTypes;
	const VideoMediaTypes&	getSupportedVideoMediaTypes() const { return mSupportedVideoMediaTypes; }

	//void					update();	

	bool					startCapture( std::size_t indexMediaType );
	bool					stopCapture();
	bool					isCapturing() const				{ return mIsCapturing; }
	bool					getCapturedImage( MemoryBuffer& buffer, unsigned int& sequenceNumber, LONGLONG& timestamp ) const;


private:
	bool					initialize();

	mutable CRITICAL_SECTION					mCriticalSection;
	VideoMediaTypes								mSupportedVideoMediaTypes;

	COMObjectSharedPtr<IMoniker>				mMoniker;
	COMObjectSharedPtr<IGraphBuilder>			mGraphBuilder;
	COMObjectSharedPtr<ICaptureGraphBuilder2>	mCaptureGraphBuilder2;
	COMObjectSharedPtr<ISampleGrabber>			mSampleGrabberFilter;
	COMObjectSharedPtr<IBaseFilter>				mSourceFilter;
	
	class SampleGrabberCallback;
	SampleGrabberCallback*						mSampleGrabberCallback;
	bool										mIsCapturing;
};


}